package com.splic.product.service.impl;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import com.alicp.jetcache.anno.CacheInvalidate;
import com.alicp.jetcache.anno.Cached;
import com.github.pagehelper.Page;
import com.splic.common.core.DeviceContext;
import com.splic.common.exception.BusinessException;
import com.splic.common.utils.DateUtils;
import com.splic.common.utils.StringUtils;
import com.splic.product.domain.GoodsQueryDto;
import com.splic.product.domain.GoodsType;
import com.splic.product.domain.Product;
import com.splic.product.dto.GoodsDto;
import com.splic.product.dto.GoodsTypeDto;
import com.splic.product.mapper.GoodsTypeMapper;
import com.splic.product.service.ProductService;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.splic.product.mapper.GoodsMapper;
import com.splic.product.domain.Goods;
import com.splic.product.service.GoodsService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 订阅套餐Service业务层处理
 * 
 * @author singe
 * @date 2022-01-04
 */
@Service
public class GoodsServiceImpl implements GoodsService
{
    @Autowired
    private GoodsMapper goodsMapper;
    @Autowired
    private GoodsTypeMapper goodsTypeMapper;
    @Autowired
    private ProductService productServiceImpl;

    /**
     * 查询订阅套餐
     * 
     * @param id 订阅套餐主键
     * @return 订阅套餐
     */
    @Override
    @Cached(name = "goods:", key = "#id" ,expire = 30,timeUnit = TimeUnit.MINUTES)
    public Goods selectGoodsById(Long id)
    {
        return goodsMapper.selectGoodsById(id);
    }

    /**
     * 查询订阅套餐列表
     * 
     * @param goods 订阅套餐
     * @return 订阅套餐
     */
    @Override
    public List<GoodsDto> selectPageList(GoodsQueryDto goodsQueryDto)
    {
        Page<GoodsDto> goodsDtoPage = new Page<>();

        Page<Goods> goodsPage = goodsMapper.selectGoodsList(goodsQueryDto);
        if(CollectionUtils.isNotEmpty(goodsPage)){
            Set<Long> goodsTypeIdSet = goodsPage.stream().map(Goods::getGoodsTypeId).collect(Collectors.toSet());
            Map<Long,String> goodsTypeMap = null;
            if(CollectionUtils.isNotEmpty(goodsTypeIdSet)){
                List<GoodsType> goodsTypeList = goodsTypeMapper.getByIds(goodsTypeIdSet);
                if(CollectionUtils.isNotEmpty(goodsTypeList)){
                    goodsTypeMap = goodsTypeList.stream().collect(Collectors.toMap(GoodsType::getId,GoodsType::getName));
                }
            }

            Set<Long> prodcutIdSet = goodsPage.stream().map(Goods::getProductId).collect(Collectors.toSet());
            Map<Long,String> productMap = null;
            if(CollectionUtils.isNotEmpty(prodcutIdSet)){
                List<Product> productList = productServiceImpl.getByIds(prodcutIdSet);
                if(CollectionUtils.isNotEmpty(productList)){
                    productMap = productList.stream().collect(Collectors.toMap(Product::getId,Product::getName));
                }
            }

            GoodsDto dto = null;
            for(Goods g :goodsPage){
                dto = new GoodsDto();
                BeanUtils.copyProperties(g,dto);
                if(goodsTypeMap!= null){
                    dto.setGoodsTypeName(goodsTypeMap.get(g.getGoodsTypeId()));
                }
                if(productMap != null){
                    dto.setProductName(productMap.get(g.getProductId()));
                }
                goodsDtoPage.add(dto);
            }
        }
        goodsDtoPage.setTotal(goodsPage.getTotal());
        return goodsDtoPage;
    }

    /**
     * 查询订阅套餐列表
     *
     * @param goods 订阅套餐
     * @return 订阅套餐
     */
    @Override
    public List<Goods> selectGoodsList(GoodsQueryDto goodsQueryDto)
    {
        return goodsMapper.selectGoodsList(goodsQueryDto);
    }

    /**
     * 新增订阅套餐
     * 
     * @param goods 订阅套餐
     * @return 结果
     */
    @Override
    public int insert(Goods goods)
    {
        goods.setCreateTime(DateUtils.getNowDate());
        return goodsMapper.insert(goods);
    }

    /**
     * 修改订阅套餐
     * 
     * @param goods 订阅套餐
     * @return 结果
     */
    @Override
    public int update(Goods goods)
    {
        goods.setUpdateTime(DateUtils.getNowDate());
        return goodsMapper.update(goods);
    }


    /**
     * 删除订阅套餐信息
     * 
     * @param id 订阅套餐主键
     * @return 结果
     */
    @Override
    public int deleteById(Long id)
    {
        return goodsMapper.deleteById(id);
    }
    /**
     * 修改订阅套餐
     *
     * @param goods 订阅套餐信息
     * @return 结果
     */
    @Override
    @Transactional
    @CacheInvalidate(name = "goods:", key = "#goods.id")
    public int saveOrUpdate(Goods goods)
    {
        GoodsType type = goodsTypeMapper.selectGoodsTypeById(goods.getGoodsTypeId());
        if ("time".equals(type.getServiceNature())) {
            goods.setCycle(goods.getCycle1());
        }
        if(goods.getId() != null){
            goods.setUpdateTime(new Date());
            return goodsMapper.update(goods);
        }else{
            goods.setCreateTime(new Date());
            return goodsMapper.insert(goods);
        }
    }

    @Override
    public List<Goods> getGoodsList(String packageKey) {
        List<GoodsType> goodsTypeList = null;
        if(StringUtils.isNotEmpty(packageKey)){
            Product product = productServiceImpl.getByPackageKey(packageKey);
            if (product == null){
                throw new BusinessException("查询不到当前应用。");
            }
            goodsTypeList = goodsTypeMapper.getByProductId(product.getId());
            if(CollectionUtils.isEmpty(goodsTypeList)){
                throw new BusinessException("当前应用下没有服务套餐。");
            }
        }
        GoodsQueryDto dto = new GoodsQueryDto();
        String version = DeviceContext.getVersion();
        dto.setIsShelf(1);
        //版本号为测试时  返回所有数据
        if(StringUtils.isNotEmpty(version)){
            String [] versionArr = version.split("\\.");
            //版本号第四段为test时 才判定为测试版本
            if (versionArr.length == 4 && StringUtils.equalsIgnoreCase("test",versionArr[3])){
                dto.setIsShelf(null);
            }

        }
        dto.setGoodsTypeIdList(goodsTypeList.stream().map(GoodsType::getId).collect(Collectors.toList()));
        return this.selectGoodsList(dto);
    }
}
